#ifndef VECTOR_H_
#define VECTOR_H_

#include <vector>
#include <sstream>
#include <cmath>

class Vector
{
private:
	std::vector<double> v_;

public:
	Vector(std::size_t length) : v_(length, 0.0)
	{
	}

	Vector(const std::vector<double>& v) : v_(v)
	{
	}

	std::size_t length() const
	{
		return v_.size();
	}

	double operator[](int i) const { return v_[i]; }

	double& operator[](int i) { return v_[i]; }

	bool operator==(const Vector& v) const
	{
		for(std::size_t i=0;i<length();i++)
		{
			if((*this)[i]!=v[i]) {return false;};
		}
		return true;
	}

	bool operator!=(const Vector& v) const
	{
		return (!((*this)==v));
	}

	Vector operator!() const
	{
		Vector r(length());
		for(std::size_t i=0;i<length();i++) { r[i]=0.0-(*this)[i]; }
		return r;
	}

	Vector operator*(double k) const
	{
		Vector r(length());
		for(std::size_t i=0;i<length();i++) { r[i]=(*this)[i]*k; }
		return r;
	}

	Vector operator/(double k) const
	{
		return ((*this)*(1.0/k));
	}

	Vector operator+(const Vector& v) const
	{
		Vector r(length());
		for(std::size_t i=0;i<length();i++) { r[i]=(*this)[i]+v[i]; }
		return r;
	}

	Vector operator-(const Vector& v) const
	{
		return ((*this)+(!v));
	}

	double operator*(const Vector& v) const
	{
		double sum=0.0;
		for(std::size_t i=0;i<length();i++)
		{
			sum+=(*this)[i]*v[i];
		}
		return sum;
	}

	double norm() const
	{
		return sqrt((*this)*(*this));
	}

	Vector unit() const
	{
		return (*this)/norm();
	}

	std::string to_string() const
	{
		std::ostringstream output;
		for(std::size_t i=0;i<length();i++) { output << (*this)[i] << (i+1<length() ? " " : ""); }
		return output.str();
	}

	static Vector from_string(const std::string& str)
	{
		std::vector<double> v;
		std::istringstream input(str);
		while(input.good())
		{
			double val=0.0;
			input >> val;
			v.push_back(val);
		}
		return Vector(v);
	}
};

#endif /* VECTOR_H_ */
